home *** CD-ROM | disk | FTP | other *** search
- From: Tom Truscott <decvax!mcnc!rti-sel!trt>
- Subject: wm - a window manager (part 2 of 4)
- Newsgroups: mod.sources
- Approved: john@genrad.UUCP
-
- Mod.sources: Volume 2, Issue 32
- Submitted by: Tom Truscott <decvax!mcnc!rti-sel!trt>
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # Makefile
- # wm.h
- # cmd.c
- # curses.c
- # getch.c
- # hacks.c
- # help.c
- # This archive created: Fri Aug 2 13:13:15 1985
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'Makefile'" '(2215 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- #
- # Makefile for wm
- #
-
- # Flags for the C compiler.
- CFLAGS = -O
-
- # Flags for loader. You probably do not need any.
- LDFLAGS =
-
- # Final resting place of wm executable.
- BIN = /usr/local
-
- # Name of owner and group that you want installed wm to have.
- OWNER = bin
- GROUP = bin
-
- # Version of libcurses wm is linked with. This *must* be
- # the version that is distributed with wm, since it contains
- # several bug fixes necessary to the correct operation of wm.
- LIBS = -lcurses -ltermcap
-
- OBJS = cmd.o curses.o getch.o hacks.o help.o misc.o \
- save.o shell.o vterm.o wlist.o wm.o
- XSRCS = cmd.c curses.c getch.c hacks.c help.c misc.c \
- save.c shell.c vterm.c wlist.c wm.c
-
- wm: $(OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o wm
-
- $(OBJS): wm.h
-
- lint:
- lint -hbux $(SRCS)
-
- clean:
- /bin/rm -f *.o wm core *.out
-
- install: wm
- install -o $(OWNER) -g $(GROUP) -s wm $(DESTDIR)/$(BIN)
-
- depend:
- cat </dev/null >x.c
- for i in ${SRCS}; do \
- (echo `basename $$i .c`.o: $$i >>makedep; \
- /bin/grep '^#[ ]*include' x.c $$i | sed \
- -e 's,<\(.*\)>,"/usr/include/\1",' \
- -e 's/:[^"]*"\([^"]*\)".*/: \1/' \
- -e 's/\.c/.o/' >>makedep); done
- echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
- echo '$$r makedep' >>eddep
- echo 'w' >>eddep
- cp Makefile Makefile.bak
- ed - Makefile < eddep
- rm eddep makedep x.c
- echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
- echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
- echo '# see make depend above' >> Makefile
-
- # DO NOT DELETE THIS LINE -- make depend uses it
-
- cmd.o: cmd.c
- cmd.o: wm.h
- curses.o: curses.c
- curses.o: wm.h
- getch.o: getch.c
- getch.o: wm.h
- getch.o: /usr/include/signal.h
- getch.o: /usr/include/setjmp.h
- getch.o: /usr/include/sys/time.h
- hacks.o: hacks.c
- hacks.o: wm.h
- help.o: help.c
- help.o: wm.h
- misc.o: misc.c
- misc.o: wm.h
- save.o: save.c
- save.o: wm.h
- shell.o: shell.c
- shell.o: wm.h
- shell.o: /usr/include/signal.h
- shell.o: /usr/include/errno.h
- vterm.o: vterm.c
- vterm.o: wm.h
- wlist.o: wlist.c
- wlist.o: wm.h
- wm.o: wm.c
- wm.o: wm.h
- wm.o: /usr/include/signal.h
- wm.o: /usr/include/sys/wait.h
- wm.o: /usr/include/sys/time.h
- wm.o: /usr/include/sys/resource.h
- # DEPENDENCIES MUST END AT END OF FILE
- # IF YOU PUT STUFF HERE IT WILL GO AWAY
- # see make depend above
- SHAR_EOF
- if test 2215 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 2215 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'wm.h'" '(6227 characters)'
- if test -f 'wm.h'
- then
- echo shar: will not over-write existing file "'wm.h'"
- else
- sed 's/^X//' << \SHAR_EOF > 'wm.h'
- /*
- *************
- * DISTRIBUTION NOTICE July 30 1985
- * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
- * Research Triangle Institute, (919) 541-7005.
- * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
- * Naval Research Laboratory, (202) 767-3365.
- * No claims or warranties of any sort are made for this distribution.
- * General permission is granted to copy, but not for profit,
- * any of this distribution, provided that this notice
- * is always included in the copies.
- *************
- */
- /*
- * definitions for wm
- */
-
- #include "curses.h"
- #include <sys/types.h>
- #include <ctype.h>
-
- #define CURSEASSIST /* give curses a hand, sigh. */
- #define SET_WINDOW /* assist all-wonderful scrolling rectangles */
- #define GAGMEKEYPAD /* gross hack for arrow keys */
- /*#define SNEAKYTERMCAP /* /tmp termcap kludge */
-
- /* define TERMINFO if we are using a terminfo version of curses */
- #ifdef A_STANDOUT
- #define TERMINFO
- #endif
-
- #ifdef TERMINFO
- /* define FASTTERMINFO if your terminfo has a clever doupdate */
- /*#define FASTTERMINFO /**/
- /* define BUGGYTERMINFO if your terminfo has 'certain bugs' */
- #define BUGGYTERMINFO /**/
- #endif
-
- /*
- * Definitions for curses
- */
- #define wcury(w) ((w)->_cury) /* current (y,x) in window w */
- #define wcurx(w) ((w)->_curx)
- #define wbegy(w) ((w)->_begy) /* window offset from origin */
- #define wbegx(w) ((w)->_begx)
- #define wlines(w) ((w)->_maxy) /* # lines/cols in window w */
- #define wcols(w) ((w)->_maxx)
- #define cursrow() wcury(curscr) /* current (y,x) on screen */
- #define curscol() wcurx(curscr)
-
- /* stuff dependent on the version of curses */
- #ifdef TERMINFO
- #undef GAGMEKEYPAD
- #ifdef FASTTERMINFO
- #undef CURSEASSIST
- #endif
- #undef wlines
- #undef wcols
- #define wlines(w) ((w)->_maxy+1) /* # lines/cols in window w */
- #define wcols(w) ((w)->_maxx+1)
- #include <term.h>
- /* undefine one of the more annoying definitions in term.h */
- #ifdef lines
- #undef lines
- #endif
- extern WINDOW *newscr;
- #define Untouchwin(wp) untouchwin(wp),untouchwin(newscr)
- #ifdef CURSEASSIST
- /* curseassist cheats big */
- #define Cmove(y,x) wmove(curscr,y,x),wmove(newscr,y,x)
- #define Cinsertln() winsertln(curscr),winsertln(newscr)
- #define Cdeleteln() wdeleteln(curscr),wdeleteln(newscr)
- #endif
- #else
- extern int *_putchar();
- #define putp _puts
- #define enter_ca_mode TI
- #define cursor_address CM
- #define flash_screen VB
- #define enter_standout_mode SO
- #define exit_standout_mode SE
- #define move_standout_mode MS
- #define insert_line AL
- #define delete_line DL
- #define change_scroll_region CS
- #define scroll_reverse SR
- #define save_cursor SC
- #define restore_cursor RC
- #define insert_character IC
- #define insert_null_glitch IN
- #define enter_insert_mode IM
- #define exit_insert_mode EI
- #define delete_character DC
- #define scroll_forward NL
- #define cursor_down DO
- #define cursor_up UP
- #define Untouchwin(wp) untouchwin(wp)
- #ifdef CURSEASSIST
- /* curseassist cheats big */
- #define Cmove(y,x) wmove(curscr,y,x)
- #define Cinsertln() winsertln(curscr)
- #define Cdeleteln() wdeleteln(curscr)
- #endif
- #endif
-
- /* key pad atrocities follow */
- extern char tty_text[], keycap[];
- extern int tty_textlen, tty_backcnt;
- #ifndef KEY_BACKSPACE
- #define KEY_BACKSPACE 0401
- #define KEY_UP 0402
- #define KEY_DOWN 0403
- #define KEY_LEFT 0404
- #define KEY_RIGHT 0405
- #define KEY_HOME 0406
- #endif
- #ifndef GAGMEKEYPAD
- #define tty_getch tty_realgetch
- #endif
-
- /*
- * The number of active windows is limited by the number of
- * open files a process (i.e., main) may have,
- * the number of processes a user or the whole system can have,
- * and (on an 11 but not a VAX) the memory for the per-window curses buffers.
- * Also, window names are limited to 0..9, i.e. at most 10 windows.
- */
- #define MAXWINDOWS 10 /* windows #0..#9 */
-
- #define ESC '\033' /* char for virtual terminal functions */
- #define CANCEL1 '\033' /* char to cancel wm command */
- #define CANCEL2 '\177' /* char to cancel wm command */
-
- #define MINWINDOW 1 /* change this to 0 to permit window #0 */
- #define iswindow(w) ((w)>=MINWINDOW && (w)<MAXWINDOWS && (win[w].flags&INUSE))
- #define ctoi(c) ((c)-'0') /* convert ascii digit to int */
- #define itoc(i) ((i)+'0') /* convert int to ascii digit */
-
- /*
- * Global data with miscellaneous information about each window
- */
- struct win_struct
- {
- int flags; /* window status bits */
- #define INUSE 001 /* window is in use */
- #define XFLEX 002 /* # of columns is COLS (depends on terminal type) */
- #define YFLEX 004 /* # of rows is ROWS ( "" "" "" "" ) */
- #define FAST 010 /* window can scroll 'quickly' (not redrawn) */
- #define BROWSE 020 /* window is in 'browse' mode */
- #define BLOCKED 040 /* window updates are being delayed */
- int next; /* next window in list */
- char covers[MAXWINDOWS]; /* TRUE for windows we're on top of */
- WINDOW *wptr; /* ptr to small curses win to be displayed */
- WINDOW *boxbot, *boxtop; /* ptrs to curses wins for box, or NULL */
- WINDOW *boxright, *boxleft; /* ptrs to curses wins for box, or NULL */
- char pend[4]; /* characters in partial escape sequence */
- int pid; /* pid of this window's shell */
- int pty; /* fildes of pty to/from this win's shell */
- };
-
- /*
- * Handy macros
- */
- #define MAX(a,b) ((a)>=(b)? (a): (b))
- #define MIN(a,b) ((a)<=(b)? (a): (b))
-
- /*
- * External variables.
- */
- extern struct win_struct win[]; /* array of windows */
- extern int botw, topw, lastw; /* bottom, top, last window */
- extern int prefix; /* WM command prefix character */
- extern char savefile[]; /* name of save/restore file */
- extern char shellname[]; /* name of shell */
- extern char shellpgm[]; /* pathname of shell */
- extern int configflag; /* true if window config. has changed */
- extern time_t msgbirth; /* time last message was displayed */
- #ifndef TERMINFO
- extern char *change_scroll_region, *save_cursor, *restore_cursor;
- extern char *set_window;
- #endif
- extern int has_scroll_window, has_scroll_region, has_insdel_line;
-
- /*
- * Functions returning a non-int value
- */
- XFILE *fopen();
- char *sprintf(), *strcpy(), *strcat(), *rindex(), *getenv();
- char *mkprint(), *termcap(), *WPrompt(), *plural();
- double *Malloc(); /* if only malloc were declared this way */
-
- #define alloc(n,type) ((type*)Malloc((unsigned)((n)*sizeof(type))))
- SHAR_EOF
- if test 6227 -ne "`wc -c < 'wm.h'`"
- then
- echo shar: error transmitting "'wm.h'" '(should have been 6227 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'cmd.c'" '(7983 characters)'
- if test -f 'cmd.c'
- then
- echo shar: will not over-write existing file "'cmd.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'cmd.c'
- /*
- *************
- * DISTRIBUTION NOTICE July 30 1985
- * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
- * Research Triangle Institute, (919) 541-7005.
- * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
- * Naval Research Laboratory, (202) 767-3365.
- * No claims or warranties of any sort are made for this distribution.
- * General permission is granted to copy, but not for profit,
- * any of this distribution, provided that this notice
- * is always included in the copies.
- *************
- */
- /*
- * Command interpreter for WM.
- */
-
- #include "wm.h"
-
- /*
- * Command definitions
- */
- # define DUMPWINDOW 'd' /* dump contents of current window to file */
- # define FITWINDOW 'f' /* Find best unobscured place for a window */
- # define HELP2 'h' /* Command summary */
- # define HELP1 '?' /* Command summary */
- # define IDENTWINDOW 'i' /* print name of current window */
- # define KILLWINDOW 'k' /* get rid of this window forever */
- # define LASTWINDOW 'l' /* change to Last-used window */
- # define MOVEWINDOW 'm' /* Move locn and/or change size of window */
- # define NEWWINDOW 'n' /* make New window */
- # define PREFIX 'p' /* change prefix character */
- # define QUIT 'q' /* close up everything and Quit */
- # define REDRAW 'r' /* Redraw all windows */
- # define SAVEWINDOWS 's' /* save current window configuration */
- # define TERMCAP 't' /* Reset $TERM and $TERMCAP of current window */
- # define SUSPEND 'z' /* suspend wm */
- # define NOOP1 ' ' /* no-op */
- # define NOOP2 '\n' /* no-op */
- # define NOOP3 '\r' /* no-op */
-
-
- /*
- * Execute a WM command.
- */
- docmd(cmd)
-
- int cmd; /* IN: command code */
- {
- register int w, tmpw;
- int begline, begcol, lines, cols; /* window parameters */
- char *s;
- register WINDOW *wp;
-
-
- switch (cmd)
- {
- case CANCEL1:
- case CANCEL2:
- showmsg("Canceled.");
- break;
-
- case NEWWINDOW:
- tmpw = topw;
- if ((w = GetSlot()) < 0) {
- showmsg("Sorry, can't create any more windows.");
- break;
- }
- if (NewWindow(w,LINES-1,COLS,0,0))
- break;
- WListAdd(w);
- if (getbounds(w, TRUE) != 0)
- break; /* getbounds will have freed the window */
- lastw = tmpw;
- showmsg("Created new window #%d.", w);
- winchanged(w);
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- w = ctoi(cmd);
- if ( ! iswindow(w))
- showmsg("No such window #%d.", w);
- else if (w == topw)
- showmsg("You're already in window #%d.", w);
- else
- {
- lastw = topw;
- WListDelete(w);
- WListAdd(w);
- RedrawScreen();
- showmsg("Changed to window #%d.", w);
- }
- break;
-
- case LASTWINDOW:
- if (iswindow(lastw) && lastw!=topw)
- {
- w=lastw;
- lastw=topw;
- WListDelete(w);
- WListAdd(w);
- RedrawScreen();
- showmsg("Changed back to window #%d.", w);
- }
- else
- showmsg("No last window.");
- break;
-
- case MOVEWINDOW:
- w = topw;
- wp = win[w].wptr;
- lines = wlines(wp); cols = wcols(wp);
- begline = wbegy(wp); begcol = wbegx(wp);
- if (getbounds(w, FALSE) != 0)
- break;
- wp = win[w].wptr;
- if (lines == wlines(wp) && cols == wcols(wp)) {
- if (begline == wbegy(wp) && begcol == wbegx(wp)) {
- showmsg("Window unchanged.");
- break;
- }
- }
- else
- SetTerm(w, 2);
- showmsg("Moved window #%d.", w);
- winchanged(w);
- break;
-
- case FITWINDOW:
- showmsg("Fit which window?");
- if ((w = askwindow()) < 0)
- break;
- if (fitwindow(w, &lines, &cols, &begline, &begcol) < 0) {
- showmsg("Sorry, cannot find unobscured placement.");
- break;
- }
- wp = win[w].wptr;
- tmpw = 1; /* shameless misuse of variable */
- if (lines == wlines(wp) && cols == wcols(wp)) {
- tmpw = 0;
- if (begline == wbegy(wp) && begcol == wbegx(wp)) {
- showmsg("Window already has best fit.");
- break;
- }
- }
- if (NewWindow(w,lines,cols,begline,begcol)) {
- WListDelete(w);
- break;
- }
- if (tmpw)
- SetTerm(w, 2);
- RedrawScreen();
- showmsg("Moved window #%d.", w);
- winchanged(w);
- break;
-
- case KILLWINDOW:
- showmsg("Kill which window?"); /* enter window name */
- if ((w = askwindow()) < 0)
- break;
- if (w==topw)
- {
- showmsg("Can't kill the current window.");
- break;
- }
- WListDelete(w); KillShell(w); FreeWindow(w);
- RedrawScreen();
- showmsg("Killed window #%d.", w);
- if (w==lastw) lastw = -1;
- configflag = TRUE;
- break;
-
- case IDENTWINDOW:
- IdentWindows();
- break;
-
- case DUMPWINDOW:
- if ((s = WPrompt("dump file", "wmdump")) == NULL)
- break;
- else if (DumpWindow(topw, s) == 0)
- showmsg("Dumped contents of top window to file '%s'.", s);
- else
- showmsg("Sorry, can't open dump file '%s'.", s);
- break;
-
- case REDRAW:
- ClearScreen();
- RedrawScreen();
- break;
-
- case TERMCAP:
- SetTerm(topw, 3);
- break;
-
- case HELP1:
- case HELP2:
- ClearScreen();
- helpmsg();
- (void) tty_getch();
- ClearScreen();
- RedrawScreen();
- break;
-
- case PREFIX:
- showmsg("Enter new WM prefix character.");
- prefix = tty_getch();
- showmsg("New WM prefix character is '%s'.", mkprint(prefix));
- configflag = TRUE;
- break;
-
- case SUSPEND:
- suspend();
- break;
-
- case SAVEWINDOWS:
- if ((s = WPrompt("save file", savefile)) == NULL)
- break;
- (void) strcpy(savefile, s);
- if (Save(savefile) != 0)
- {
- showmsg("Saved current window configuration in '%s'.", savefile);
- configflag = FALSE;
- }
- else showmsg("Sorry, can't save current window configuration.");
- break;
-
- case QUIT:
- return(TRUE);
-
- case NOOP1:
- case NOOP2:
- case NOOP3:
- break;
-
- default:
- showmsg("Invalid command '%s': use 'h' command for help.",mkprint(cmd));
- break;
- }
-
- return(FALSE);
- }
-
- /*
- * suspend w/ job control if using csh, otherwise spawn subshell.
- * This could be integrated into curses tstp(),
- * but I wasn't sure that could be done correctly,
- * since it is impossible(?) to determine if the parent shell
- * knows job control.
- */
- suspend()
- {
- register int rc;
- #ifndef TERMINFO
- register int ttyflags;
- #endif
-
- /* If wm's parent is init, then we better not suspend with TSTP!
- * Unfortunately, this heuristic fails if the user used rlogin,
- * since wm's parent would then be rlogind. We can only hope
- * the user knows what he is doing.
- */
- if (getppid() != 1
- && (rc = strlen(shellname)) >= 3
- && strcmp(shellname+rc-3, "csh") == 0) {
- showmsg("Suspending.");
- tstp();
- showmsg("WM resumed.");
- return;
- }
-
- showmsg("Spawning a sub-shell ...");
- (void) movecursor(LINES-1, 0);
- #ifndef TERMINFO
- ttyflags = _tty.sg_flags;
- #endif
- endwin();
- putchar('\n'); /* scroll up, for neatness */
- (void) fflush(stdout);
-
- rc = system(shellpgm);
- #ifdef TERMINFO
- #ifdef BUGGYTERMINFO
- /* Alas, buggyterminfo apparently does not re-remember the virgin state
- * or correct for a baud-rate change */
- #endif
- fixterm();
- #else
- savetty(); /* re-remember the virgin state */
- _tty.sg_flags = ttyflags;
- (void) ioctl(_tty_ch, TIOCSETN, (char *)&_tty);
- #endif
- if (enter_ca_mode)
- putp(enter_ca_mode);
- wrefresh(curscr);
- /* we could diagnose things better here */
- if (rc == 127)
- showmsg("Cannot spawn a shell!");
- else
- showmsg("Returning to WM.");
- }
-
- /*
- * Set 'configflag' to indicate change affecting wmrc file.
- * If this window is full-width or full-length,
- * set the corresponding 'flex' flag.
- * Warn user if this is a 'slow' window.
- */
- winchanged(w)
- register int w;
- {
- register WINDOW *wp;
- static int full_width_warning = FALSE;
-
- configflag = TRUE;
- win[w].flags &= ~(XFLEX|YFLEX);
- wp = win[w].wptr;
- if (wcols(wp) == COLS)
- win[w].flags |= XFLEX;
- if (wlines(wp) == LINES-1)
- win[w].flags |= YFLEX;
- WObscure(); /* recompute obscured window info */
- if (!(win[w].flags&FAST)) {
- if (wcols(wp) != COLS) {
- showmsg("\007Non full-width window #%d will scroll slowly!", w);
- return;
- }
- if (full_width_warning)
- return;
- full_width_warning = TRUE;
- showmsg("\007This terminal scrolls split-screen windows slowly.");
- }
- }
- SHAR_EOF
- if test 7983 -ne "`wc -c < 'cmd.c'`"
- then
- echo shar: error transmitting "'cmd.c'" '(should have been 7983 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'curses.c'" '(11058 characters)'
- if test -f 'curses.c'
- then
- echo shar: will not over-write existing file "'curses.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'curses.c'
- /*
- *************
- * DISTRIBUTION NOTICE July 30 1985
- * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
- * Research Triangle Institute, (919) 541-7005.
- * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
- * Naval Research Laboratory, (202) 767-3365.
- * No claims or warranties of any sort are made for this distribution.
- * General permission is granted to copy, but not for profit,
- * any of this distribution, provided that this notice
- * is always included in the copies.
- *************
- */
- /*
- * curses.c R. Jacob
- */
-
- #include "wm.h"
-
- static WINDOW *mw=NULL; /* message window */
- static WINDOW *cmw=NULL; /* blank message window */
- time_t msgbirth = 0;
-
-
- /*
- * Set up win structure and associated junk for new window w.
- * Returns 0 if sucessful, else -1.
- */
- NewWindow(w, lines, cols, begline, begcol)
-
- register int w;
- int lines, cols, begline, begcol;
- {
- register WINDOW *wp, *owp;
-
-
- if ((wp=newwin(lines,cols,begline,begcol)) == NULL) {
- showmsg("\007Cannot %sconstruct window #%d!.",
- ((win[w].flags&INUSE)? "re": ""), w);
- FreeWindow(w);
- return(-1);
- }
- leaveok(wp, TRUE);
-
- /* If the window is already in use, copy old window to new one
- * anchored at bottom left of the windows.
- * We move the bottom left of both windows to the bottom left
- * of the screen, overwrite, then move the windows back.
- * (Actually, we do not bother to move the old window back.)
- */
- if (win[w].flags&INUSE) {
- owp = win[w].wptr;
- mvwin(owp, LINES-wlines(owp), 0);
- mvwin(wp, LINES-wlines(wp), 0);
- overwrite(owp, wp);
- mvwin(wp, begline, begcol);
- wmove(wp, wcury(owp) + (wlines(wp)-wlines(owp)), wcurx(owp));
- FreeWindow(w);
- }
-
- win[w].wptr = wp;
-
- if (MakeBorders(w) != 0)
- {
- showmsg("\007Cannot construct borders for window #%d!.", w);
- FreeWindow(w);
- return(-1);
- }
-
- win[w].flags |= INUSE;
- if (has_scroll_window
- || (cols == COLS
- && (has_scroll_region || has_insdel_line || lines == LINES-1)))
- win[w].flags |= FAST;
-
- return(0);
- }
-
- /*
- * Deallocate win structure and associated junk.
- */
- XFreeWindow(w)
-
- register int w;
- {
- win[w].flags = 0;
-
- if (win[w].wptr) {delwin(win[w].wptr); win[w].wptr = 0;}
- if (win[w].boxbot) {delwin(win[w].boxbot); win[w].boxbot = 0;}
- if (win[w].boxtop) {delwin(win[w].boxtop); win[w].boxtop = 0;}
- if (win[w].boxright) {delwin(win[w].boxright); win[w].boxright = 0;}
- if (win[w].boxleft) {delwin(win[w].boxleft); win[w].boxleft = 0;}
- }
-
- #ifdef notdef
- /*
- * Redraw window w.
- */
- RedrawWindow(w)
-
- register int w;
- {
- register WINDOW *wp;
-
- if (!iswindow(w))
- return;
- if (wp=win[w].wptr) { touchwin(wp); wrefresh(wp); }
- if (wp=win[w].boxbot) { touchwin(wp); wrefresh(wp); }
- if (wp=win[w].boxtop) { touchwin(wp); wrefresh(wp); }
- if (wp=win[w].boxright) { touchwin(wp); wrefresh(wp); }
- if (wp=win[w].boxleft) { touchwin(wp); wrefresh(wp); }
- }
- #endif
-
- /*
- * Redraw the entire screen.
- * Uses Curses' standard screen, stdscr.
- */
- RedrawScreen()
- {
- register int w, base;
- register WINDOW *wp;
-
- /* speed hack: start with the topmost full-screen window.
- * (Smarter hacks come to mind, but this one is easy.)
- */
- base = botw;
- for (w=base; w>=0; w=win[w].next)
- if ((wp = win[w].wptr) && wcols(wp) == COLS && wlines(wp) >= LINES-1)
- base = w;
-
- werase(stdscr);
-
- /* Write contents of all windows into stdscr, then refresh.
- */
- for (w=base; w>=0; w=win[w].next)
- {
- if (wp=win[w].wptr) overwrite(wp, stdscr);
- if (wp=win[w].boxtop) overwrite(wp, stdscr);
- if (wp=win[w].boxbot) overwrite(wp, stdscr);
- if (wp=win[w].boxright) overwrite(wp, stdscr);
- if (wp=win[w].boxleft) overwrite(wp, stdscr);
- }
-
- if (msgbirth)
- overwrite(mw, stdscr);
- touchwin(stdscr);
- wrefresh(stdscr);
- RestoreCursor();
- }
-
- /*
- * Identify windows.
- * Draw each window in turn, from bottom to top.
- * Uses Curses' standard screen, stdscr.
- */
- IdentWindows()
- {
- register int w; /* window index */
- register WINDOW *wp;
- register int canceled=FALSE; /* TRUE if user cancels this command */
- register int c;
-
-
- /* Erase the screen (and stdscr).
- */
- ClearScreen();
-
- /* Write contents of each window into stdscr, then refresh.
- */
- for (w=botw; w>=0; w=win[w].next)
- {
- if (wp=win[w].wptr) overwrite(wp, stdscr);
- if (wp=win[w].boxtop) overwrite(wp, stdscr);
- if (wp=win[w].boxbot) overwrite(wp, stdscr);
- if (wp=win[w].boxright) overwrite(wp, stdscr);
- if (wp=win[w].boxleft) overwrite(wp, stdscr);
-
- if (canceled)
- continue;
-
- #ifdef BUGGYTERMINFO
- /* buggyterminfo seems to require this */
- touchwin(stdscr);
- #endif
- wrefresh(stdscr);
-
- if (w != topw)
- {
- showmsg("Window #%d. Hit any key to see next window.", w);
- c = tty_getch();
- if (c == CANCEL1 || c == CANCEL2)
- {
- showmsg("Canceled.");
- canceled = TRUE;
- }
- }
-
- else
- {
- showmsg("Window #%d (top window). Hit any key to continue.", w);
- (void) tty_getch();
- }
- }
-
- if (canceled)
- wrefresh(stdscr);
- RestoreMsg();
- RestoreCursor();
- }
-
- /*
- * Show message s on bottom of screen.
- */
- /*VARARGS1*/
- showmsg(s, arg1, arg2)
-
- register char *s;
- {
- char buf[256];
-
- /* Initialize message window first time 'round.
- */
- if (mw == NULL) {
- mw=newwin(1, 0, LINES-1, 0);
- cmw=newwin(1, 0, LINES-1, 0);
- if (!mw || !cmw) {
- fprintf(stderr, "Cannot create message window!\n\r");
- Shutdown(1);
- }
- leaveok(cmw, TRUE);
- werase(cmw);
- /* (leaveok for mw & cursor positioning for prompts needs thought) */
- wstandout(mw);
- }
-
- #ifdef notdef
- /* pause to let user ponder a previous message */
- if (msgbirth && *s && (t = 2-abs(msgbirth - time((time_t *)0))) > 0)
- sleep((unsigned int)t);
- #endif
-
- /* Format the message */
- (void) sprintf(buf, s, arg1, arg2);
- s = buf;
- s[wcols(mw)-1] = '\0'; /* make sure it fits */
-
- /* hack to honk but once */
- if (*s == '\007') {
- flash();
- s++;
- }
- werase(mw);
- waddstr(mw, s);
- touchwin(mw);
- wrefresh(mw);
-
- msgbirth = s[0]? time((time_t *)0): 0;
- }
-
- ZapMsgLine()
- {
- if (msgbirth) {
- touchwin(cmw);
- wrefresh(cmw);
- }
- }
-
- RestoreMsg()
- {
- if (msgbirth) {
- touchwin(mw);
- wrefresh(mw);
- }
- }
-
- /*
- * Restore cursor in top window.
- */
- RestoreCursor()
- {
- register WINDOW *wp; /* pointer to top window */
-
- wp = win[topw].wptr;
- if (movecursor(wbegy(wp)+wcury(wp), wbegx(wp)+wcurx(wp)))
- (void) fflush(stdout);
- }
-
- /*
- * Clear the whole screen
- */
- ClearScreen()
- {
- wclear(stdscr);
- wrefresh(stdscr);
- }
-
- /*
- * Creates windows containing
- * a border to surround window w
- * and puts pointer to the new windows
- * into proper places in global win[].
- * Borders appear in standout mode if
- * terminal has that capability.
- * Returns 0 if sucessful, else -1.
- */
- MakeBorders(w)
-
- register int w; /* make borders for this window */
- {
- int left, right, top, bottom; /* border flags */
- int begx, begy, cols, lines; /* window dimensions */
- register WINDOW *wp; /* window pointer */
- register int i; /* index */
-
-
- /* Get window dimensions.
- */
- wp = win[w].wptr;
- begx = wbegx(wp);
- begy = wbegy(wp);
- cols = wcols(wp);
- lines = wlines(wp);
-
-
- /* Determine which sides of the window need borders.
- */
- left = (begx > 0);
- right = (begx+cols < COLS);
- top = (begy > 0);
- bottom = (begy+lines < LINES-1); /* bottom line for msgs */
-
- if (top)
- --begy, ++lines;
- if (bottom)
- lines++;
-
-
- /* Make left border using '>'.
- */
- if (left)
- {
- if ((win[w].boxleft = wp = newwin(lines,1,begy,begx-1)) == NULL)
- return(-1);
- leaveok(wp, TRUE);
- wstandout(wp);
- for (i=0; i<lines; i++)
- waddch(wp, '>');
- }
-
-
- /* Make right border using '<'.
- */
- if (right)
- {
- if ((win[w].boxright = wp = newwin(lines,1,begy,begx+cols)) == NULL)
- return(-1);
- leaveok(wp, TRUE);
- wstandout(wp);
- for (i=0; i<lines; i++)
- waddch(wp, '<');
- }
-
-
- /* Make top border using window number.
- */
- if (top)
- {
- if ((win[w].boxtop = wp = newwin(1,cols,begy,begx)) == NULL)
- return(-1);
- leaveok(wp, TRUE);
- wstandout(wp);
- for (i=0; i<cols; i++)
- waddch(wp, itoc(w));
- }
-
-
- /* Make bottom border using window number.
- */
- if (bottom)
- {
- if ((win[w].boxbot = wp = newwin(1,cols,begy+lines-1,begx)) == NULL)
- return(-1);
- leaveok(wp, TRUE);
- wstandout(wp);
- for (i=0; i<cols; i++)
- waddch(wp, itoc(w));
- }
-
- return(0);
- }
-
- /*
- * Dump.
- * Dump the contents of the current window to file 'wmdump'
- * in the current directory.
- * Returns 0 on sucessful completion, -1 otherwise.
- */
- DumpWindow(w, dumpfile)
-
- int w; /* number of window we're to dump */
- char *dumpfile; /* file we're dumping to */
- {
- register WINDOW *wp; /* top window */
- register FILE *dfp; /* dump file pointer */
- register int line, col; /* current line, column of window */
- register int lastcol; /* column of rightmost non-blank */
- int oldy, oldx; /* saved cursor position */
-
- if ((dfp = fopen(dumpfile, "w")) == NULL)
- return(-1);
-
- wp = win[w].wptr;
- getyx(wp, oldy, oldx);
- for (line = 0; line < wlines(wp); line++)
- {
- lastcol = wcols(wp);
- while (--lastcol >= 0)
- if (toascii(mvwinch(wp, line, lastcol)) != ' ')
- break;
- for (col = 0; col <= lastcol; col++)
- putc(toascii(mvwinch(wp, line, col)), dfp);
- putc('\n', dfp);
- }
- (void) fclose(dfp);
- wmove(wp, oldy, oldx);
- return(0);
- }
-
- #define BUFLEN 80
-
- /* Prompt user for a string.
- */
- char *
- WPrompt(prompt, dflt)
-
- char *prompt; /* prompt */
- char *dflt; /* default response */
- {
- register int c; /* character in string */
- static char buf[BUFLEN+1]; /* string buffer */
- register int i=0; /* buffer index */
- int maxlen, x; /* how long can string be? */
-
- /* Print prompt and default response
- * on bottom line of screen.
- */
- showmsg("%s? [%s] ", prompt, dflt);
-
- /* Determine length of longest string
- * that will fit in window.
- */
- x = wcurx(mw);
- maxlen = (BUFLEN < wcols(mw)-2-x ? BUFLEN : wcols(mw)-2-x);
-
-
- /* Read string. Process line kill & backspace chars.
- */
- while ((c = tty_getch()) != EOF && c != '\n' && c != '\r')
- {
- if (c==CANCEL1 || c==CANCEL2) /* cancel */
- {
- showmsg("Canceled.");
- return(NULL);
- }
- if (c==erasechar() || c == KEY_BACKSPACE || c == KEY_LEFT)
- {
- if (i > 0)
- {
- i--;
- waddstr(mw, "\b \b");
- }
- }
- else if (c == killchar())
- {
- i = 0;
- wmove(mw, 0, x);
- wclrtoeol(mw);
- }
- else if (i > maxlen) /* is string too long? */
- flash();
- else if (isspace(c) || !isprint(c)) /* is character inappropriate? */
- flash();
- else /* regular char: add to string */
- {
- waddch(mw, c);
- buf[i++] = c;
- }
-
- wrefresh(mw);
- }
-
-
- /* If user didn't respond, just return default response.
- */
- if (i == 0)
- strcpy(buf, dflt);
- else
- buf[i] = '\0';
-
-
- return(buf);
- }
- SHAR_EOF
- if test 11058 -ne "`wc -c < 'curses.c'`"
- then
- echo shar: error transmitting "'curses.c'" '(should have been 11058 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'getch.c'" '(6283 characters)'
- if test -f 'getch.c'
- then
- echo shar: will not over-write existing file "'getch.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'getch.c'
- /*
- *************
- * DISTRIBUTION NOTICE July 30 1985
- * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
- * Research Triangle Institute, (919) 541-7005.
- * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
- * Naval Research Laboratory, (202) 767-3365.
- * No claims or warranties of any sort are made for this distribution.
- * General permission is granted to copy, but not for profit,
- * any of this distribution, provided that this notice
- * is always included in the copies.
- *************
- */
- #include "wm.h"
- #include <signal.h>
-
- char keycap[200]; /* termcap entries for keypad functions */
-
- int tty_backcnt; /* number of pre-read terminal chars */
- char tty_backbuf[10]; /* stack of pre-read chars */
- char tty_text[10]; /* actual text corresponding to tty_getch code */
- int tty_textlen; /* strlen(tty_text) */
-
- /*
- * Returns true iff a call to tty_realgetch would not block.
- */
- tty_inputpending()
- {
- long n;
-
- if (tty_backcnt > 0)
- return(TRUE);
- if (ioctl(0, (int)FIONREAD, (char *)&n) == 0 && n > 0)
- return(TRUE);
- return(FALSE);
- }
-
- /*
- * Read the next character from the terminal (or the backbuf),
- * return EOF if end of file, else (int)the_char, sans parity
- */
- int
- tty_realgetch()
- {
- char c;
-
- if (tty_backcnt > 0)
- c = tty_backbuf[--tty_backcnt];
- else if (read(0, &c, 1) <= 0) {
- tty_text[0] = '\0';
- tty_textlen = 0;
- return(EOF);
- }
- c = toascii(c);
- tty_text[0] = c;
- tty_text[1] = '\0';
- tty_textlen = 1;
- return(c);
- }
-
- #ifdef GAGMEKEYPAD
- init_keypad()
- {
- register int i;
- register char *p;
- char buf1[10];
-
- if (p = getcap("ks"))
- putp(p);
- for (i=1,p = "kbkukdklkrkhk0k1k2k3k4k5k6k7k8k9"; *p; i++,p+= 2) {
- (void) sprintf(buf1, "%2.2s", p);
- add_to_try(buf1, i+0400);
- }
- }
-
- /*
- ** add_to_try() (Copyright Pavel Curtis, see notice in hacks.c)
- **
- ** Construct the try for the current terminal's keypad keys.
- **
- */
- struct try
- {
- struct try *child; /* ptr to child. NULL if none */
- struct try *sibling; /* ptr to sibling. NULL if none */
- char ch; /* character at this node */
- short value; /* code of string so far. NULL if none */
- };
-
- static struct try *newtry;
-
- add_to_try(capname, code)
- char *capname;
- int code;
- {
- register struct try *ptr, *savedptr;
- register char *str, *s;
- static bool out_of_memory = FALSE;
-
- str = getcap(capname);
- if (! str || out_of_memory)
- return;
- strcat(keycap, capname); strcat(keycap, "=");
- for (s = str; *s; s++) {
- strcat(keycap, mkprint(*s));
- }
- strcat(keycap, ":");
-
- if (newtry != NULL)
- {
- ptr = newtry;
-
- for (;;)
- {
- while (ptr->ch != *str && ptr->sibling != NULL)
- ptr = ptr->sibling;
-
- if (ptr->ch == *str)
- {
- if (*(++str))
- {
- if (ptr->child != NULL)
- ptr = ptr->child;
- else
- break;
- }
- else
- {
- ptr->value = code;
- return;
- }
- }
- else
- {
- if ((ptr->sibling = alloc(1, struct try)) == NULL)
- {
- out_of_memory = TRUE;
- return;
- }
-
- savedptr = ptr = ptr->sibling;
- ptr->child = ptr->sibling = NULL;
- ptr->ch = *str++;
- ptr->value = NULL;
-
- break;
- }
- } /* end for (;;) */
- }
- else /* newtry == NULL :: First sequence to be added */
- {
- savedptr = ptr = newtry = alloc(1, struct try);
-
- if (ptr == NULL)
- {
- out_of_memory = TRUE;
- return;
- }
-
- ptr->child = ptr->sibling = NULL;
- ptr->ch = *(str++);
- ptr->value = NULL;
- }
-
- /* at this point, we are adding to the try. ptr->child == NULL */
-
- while (*str)
- {
- ptr->child = alloc(1, struct try);
-
- ptr = ptr->child;
-
- if (ptr == NULL)
- {
- out_of_memory = TRUE;
-
- ptr = savedptr;
- while (ptr != NULL)
- {
- savedptr = ptr->child;
- free((char *)ptr);
- ptr = savedptr;
- }
-
- return;
- }
-
- ptr->child = ptr->sibling = NULL;
- ptr->ch = *(str++);
- ptr->value = NULL;
- }
-
- ptr->value = code;
- return;
- }
-
- #include <setjmp.h>
- static jmp_buf jmpbuf;
-
- /*
- ** tty_getch() (Copyright Pavel Curtis, see notice in hacks.c)
- **
- ** Get an input character, but take care of keypad sequences, returning
- ** an appropriate code when one matches the input. After each character
- ** is received, set an alarm call. If no more of the sequence
- ** is received by the time the alarm goes off, pass through the sequence
- ** gotten so far.
- **
- */
- tty_getch()
- {
- /* longjmp alert! beware of register variables */
- register struct try *ptr;
- int ch;
- char buffer[10]; /* Assume no sequences longer than 10 */
- char *bufp = buffer;
- int (*oldsigalrm)();
- int sigalrm();
- bool alarmset;
-
- ptr = newtry;
- alarmset = FALSE;
- oldsigalrm = SIG_DFL; /* to quiet lint */
-
- do
- {
- if (setjmp(jmpbuf))
- break;
- ch = tty_realgetch();
- if (ch != EOF) /* returns EOF on error, too */
- *(bufp++) = ch;
-
- while (ptr != NULL && ptr->ch != ch)
- ptr = ptr->sibling;
-
- if (ptr != NULL)
- {
- if (ptr->value != NULL)
- {
- if (alarmset) {
- (void) ualarm(0L);
- (void) signal(SIGALRM, oldsigalrm);
- }
- tty_textlen = bufp-buffer;
- bcopy(buffer, tty_text, tty_textlen);
- return(ptr->value);
- }
- else
- {
- ptr = ptr->child;
- if (!alarmset) {
- alarmset = TRUE;
- oldsigalrm = signal(SIGALRM, sigalrm);
- }
- (void) ualarm(200000L);
- }
- }
-
- } while (ptr != NULL);
-
- if (alarmset) {
- (void) ualarm(0L);
- (void) signal(SIGALRM, oldsigalrm);
- }
-
- if (bufp <= buffer)
- return(EOF);
- while (--bufp > buffer)
- tty_backbuf[tty_backcnt++] = *bufp;
- return(*bufp);
- }
-
- static
- sigalrm()
- {
- longjmp(jmpbuf, 1);
- }
-
- /*
- * ualarm(usec). If this doesn't compile, just use alarm(0) and alarm(1).
- */
- #include <sys/time.h>
-
- #define MILLION 1000000L
-
- ualarm(usecs)
- long usecs;
- {
- struct itimerval it, oitv;
- register struct itimerval *itp = ⁢
-
- timerclear(&itp->it_interval);
- itp->it_value.tv_sec = usecs/MILLION;
- itp->it_value.tv_usec = usecs%MILLION;
- if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
- return (-1);
- return (oitv.it_value.tv_sec*MILLION+oitv.it_value.tv_usec);
- }
- #endif
- SHAR_EOF
- if test 6283 -ne "`wc -c < 'getch.c'`"
- then
- echo shar: error transmitting "'getch.c'" '(should have been 6283 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'hacks.c'" '(11742 characters)'
- if test -f 'hacks.c'
- then
- echo shar: will not over-write existing file "'hacks.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'hacks.c'
- /*
- *************
- * DISTRIBUTION NOTICE July 30 1985
- * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
- * Research Triangle Institute, (919) 541-7005.
- * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
- * Naval Research Laboratory, (202) 767-3365.
- * No claims or warranties of any sort are made for this distribution.
- * General permission is granted to copy, but not for profit,
- * any of this distribution, provided that this notice
- * is always included in the copies.
- *************
- */
- /*
- * hacks.c
- * curses-package routines missing in one version or another,
- * or corrections for routines in one version or another,
- * or whatever.
- */
- #include "wm.h"
-
- /*
- * Special redefinitions. We get right into the dirt here.
- */
- #ifndef TERMINFO
- #define _line _y
- #define chtype char
- #define _firstchar _firstch
- #define _lastchar _lastch
- #endif
-
- /*
- * Move physical cursor to (y,x).
- * If y is past the end of the screen, scroll the screen up.
- * This is an ugly routine in either version of curses,
- * perhaps because no one worried about this sort of thing.
- * (It would be nice to be able to request 'anywhere on line y',
- * or 'anywhere in column x', since more optimizations are then possible.)
- */
- movecursor(y,x)
- register int y, x;
- {
- if (cursrow() == y && curscol() == x)
- return(0);
- #ifdef TERMINFO
- if (y >= LINES) {
- (void) movecursor(y-1,x);
- vidattr(A_NORMAL);
- putp(scroll_forward);
- return(1);
- }
- Untouchwin(stdscr);
- leaveok(stdscr, FALSE);
- wmove(stdscr, y, x);
- wrefresh(stdscr);
- leaveok(stdscr, TRUE);
- #else
- /* Couldn't mvcur handle the move_standout_mode problem? */
- if ((curscr->_flags&_STANDOUT) && !move_standout_mode) {
- putp(exit_standout_mode);
- curscr->_flags &= ~_STANDOUT;
- }
- /* speed hack: short circuit mvcur for simple scrolling */
- if (y == LINES && curscol() == x && cursrow()+2 == y && cursor_down) {
- putp(cursor_down);
- putp(scroll_forward);
- }
- else
- mvcur(cursrow(), curscol(), y, x);
- /* Couldn't mvcur update curscr's current (y,x) coordinate? */
- if (y >= LINES)
- y = LINES-1;
- cursrow() = y; curscol() = x;
- #endif
- return(1);
- }
-
- /*
- * Make it appear that every location on the window is unchanged.
- */
- untouchwin(wp)
- register WINDOW *wp;
- {
- register int i;
-
- for (i=0; i<wlines(wp); i++) {
- wp->_firstchar[i] = _NOCHANGE;
- #ifdef TERMINFO
- wp->_lastchar[i] = _NOCHANGE;
- wp->_numchngd[i] = 0;
- #endif
- }
- }
-
- /*
- * This is a replacement overwrite() routine for both curses versions.
- * The termcap version is slow and has some minor bugs.
- * The terminfo version aligns the two windows at their origins,
- * rather than on the virtual screen, making it less useful
- * as one cannot use 'mvwin' &etc to paint one window at an
- * arbitrary place on another.
- * Neither version documents what is done with 'standout' information.
- * This version copies the standout information for each character
- * so that a truly identical copy is made, which is handy for painting.
- */
- /*********************************************************************
- * COPYRIGHT NOTICE *
- **********************************************************************
- * This software is copyright (C) 1982 by Pavel Curtis *
- * *
- * Permission is granted to reproduce and distribute *
- * this file by any means so long as no fee is charged *
- * above a nominal handling fee and so long as this *
- * notice is always included in the copies. *
- * *
- * Other rights are reserved except as explicitly granted *
- * by written permission of the author. *
- * Pavel Curtis *
- * Computer Science Dept. *
- * 405 Upson Hall *
- * Cornell University *
- * Ithaca, NY 14853 *
- * *
- * Ph- (607) 256-4934 *
- * *
- * Pavel.Cornell@Udel-Relay (ARPAnet) *
- * decvax!cornell!pavel (UUCPnet) *
- *********************************************************************/
-
- /*
- **
- ** overwrite(win1, win2)
- **
- **
- ** overwrite() writes win1 on win2 destructively.
- **
- **/
-
- overwrite(win1, win2)
- WINDOW *win1, *win2;
- {
- register chtype *w1ptr, *w2ptr;
- register int col, end_col;
- int line, offset_line, offset_col, start_line, start_col, end_line;
- short *firstchar, *lastchar;
-
- #ifdef TRACE
- if (_tracing)
- _tracef("overwrite(%o, %o) called", win1, win2);
- #endif
-
- offset_line = wbegy(win1) - wbegy(win2);
- offset_col = wbegx(win1) - wbegx(win2);
- start_line = MAX(offset_line, 0);
- start_col = MAX(offset_col, 0);
- end_line = offset_line + wlines(win1) - wlines(win2);
- end_line = wlines(win2) + MIN(end_line, 0);
- end_col = offset_col + wcols(win1) - wcols(win2);
- end_col = wcols(win2) + MIN(end_col, 0);
- firstchar = &win2->_firstchar[start_line];
- lastchar = &win2->_lastchar[start_line];
-
- for(line = start_line; line < end_line; line++)
- {
- short fc, lc;
-
- w1ptr = &win1->_line[line-offset_line][start_col-offset_col];
- w2ptr = &win2->_line[line][start_col];
- fc = lc = _NOCHANGE;
-
- for(col = start_col; col < end_col; col++)
- {
- if (*w1ptr != *w2ptr)
- {
- *w2ptr = *w1ptr;
- if (fc == _NOCHANGE)
- fc = col;
- lc = col;
- }
-
- w1ptr++;
- w2ptr++;
- }
-
- if (*firstchar == _NOCHANGE)
- {
- *firstchar = fc;
- *lastchar = lc;
- }
- else if (fc != _NOCHANGE)
- {
- if (fc < *firstchar)
- *firstchar = fc;
-
- if (lc > *lastchar)
- *lastchar = lc;
- }
-
- firstchar++;
- lastchar++;
- }
- }
-
- #ifndef TERMINFO
- /*
- * Emulators for terminfo curses procedures.
- */
-
- #ifdef SET_WINDOW
- /*
- * tparm.c (Copyright Pavel Curtis, copyright notice above applies)
- */
- /*
- * char *
- * tparm(string, parms)
- *
- * Substitute the given parameters into the given string.
- */
-
- #define STACKSIZE 20
-
- #define npush(x) if (stack_ptr < STACKSIZE) {stack[stack_ptr].num = x;\
- stack_ptr++;\
- }
- #define npop() (stack_ptr > 0 ? stack[--stack_ptr].num : 0)
- #define spop() (stack_ptr > 0 ? stack[--stack_ptr].str : (char *) 0)
-
- typedef union
- {
- unsigned int num;
- char *str;
- } stack_frame;
-
- stack_frame stack[STACKSIZE];
- static int stack_ptr;
- static char buffer[256];
- static int *param;
- static char *bufptr;
- static int variable[26];
-
- /*VARARGS1*/
- char *
- tparm(string, parms)
- char *string;
- int parms;
- {
- char len;
- int number;
- int level;
- int x, y;
-
- param = &parms;
-
- stack_ptr = 0;
- bufptr = buffer;
-
- while (*string)
- {
- if (*string != '%')
- *(bufptr++) = *string;
- else
- {
- string++;
- switch (*string)
- {
- default:
- break;
-
- case '%':
- *(bufptr++) = '%';
- break;
-
- case 'd':
- (void) sprintf(bufptr, "%d", npop());
- bufptr += strlen(bufptr);
- break;
-
- case '0':
- string++;
- len = *string;
- if ((len == '2' || len == '3') && *++string == 'd')
- {
- if (len == '2')
- (void) sprintf(bufptr, "%02d", npop());
- else
- (void) sprintf(bufptr, "%03d", npop());
-
- bufptr += strlen(bufptr);
- }
- break;
-
- case '2':
- string++;
- if (*string == 'd')
- {
- (void) sprintf(bufptr, "%2d", npop());
- bufptr += strlen(bufptr);
- }
- break;
-
- case '3':
- string++;
- if (*string == 'd')
- {
- (void) sprintf(bufptr, "%3d", npop());
- bufptr += strlen(bufptr);
- }
- break;
-
- case 'c':
- *(bufptr++) = (char) npop();
- break;
-
- case 's':
- strcpy(bufptr, spop());
- bufptr += strlen(bufptr);
- break;
-
- case 'p':
- string++;
- if (*string >= '1' && *string <= '9')
- npush(param[*string - '1']);
- break;
-
- case 'P':
- string++;
- if (*string >= 'a' && *string <= 'z')
- variable[*string - 'a'] = npop();
- break;
-
- case 'g':
- string++;
- if (*string >= 'a' && *string <= 'z')
- npush(variable[*string - 'a']);
- break;
-
- case '\'':
- string++;
- npush(*string);
- string++;
- break;
-
- case '{':
- number = 0;
- string++;
- while (*string >= '0' && *string <= '9')
- {
- number = number * 10 + *string - '0';
- string++;
- }
- npush(number);
- break;
-
- case '+':
- y = npop();
- x = npop();
- npush(x + y);
- break;
-
- case '-':
- y = npop();
- x = npop();
- npush(x - y);
- break;
-
- case '*':
- y = npop();
- x = npop();
- npush(x * y);
- break;
-
- case '/':
- y = npop();
- x = npop();
- npush(x / y);
- break;
-
- case 'm':
- y = npop();
- x = npop();
- npush(x % y);
- break;
-
- case '&':
- y = npop();
- x = npop();
- npush(x & y);
- break;
-
- case '|':
- y = npop();
- x = npop();
- npush(x | y);
- break;
-
- case '^':
- y = npop();
- x = npop();
- npush(x ^ y);
- break;
-
- case '=':
- y = npop();
- x = npop();
- npush(x == y);
- break;
-
- case '<':
- y = npop();
- x = npop();
- npush(x < y);
- break;
-
- case '>':
- y = npop();
- x = npop();
- npush(x > y);
- break;
-
- case '!':
- x = npop();
- npush(! x);
- break;
-
- case '~':
- x = npop();
- npush(~ x);
- break;
-
- case 'i':
- param[0]++;
- param[1]++;
- break;
-
- case '?':
- break;
-
- case 't':
- x = npop();
- if (x)
- {
- /* do nothing; keep executing */
- }
- else
- {
- /* scan forward for %e or %; at level zero */
- string++;
- level = 0;
- while (*string)
- {
- if (*string == '%')
- {
- string++;
- if (*string == '?')
- level++;
- else if (*string == ';')
- {
- if (level > 0)
- level--;
- else
- break;
- }
- else if (*string == 'e' && level == 0)
- break;
- }
-
- if (*string)
- string++;
- }
- }
- break;
-
- case 'e':
- /* scan forward for a %; at level zero */
- string++;
- level = 0;
- while (*string)
- {
- if (*string == '%')
- {
- string++;
- if (*string == '?')
- level++;
- else if (*string == ';')
- {
- if (level > 0)
- level--;
- else
- break;
- }
- }
-
- if (*string)
- string++;
- }
- break;
-
- case ';':
- break;
-
- } /* endswitch (*string) */
- } /* endelse (*string == '%') */
-
- if (*string == '\0')
- break;
-
- string++;
- } /* endwhile (*string) */
-
- *bufptr = '\0';
- return(buffer);
- }
- #endif
-
- /*
- * Ring Bell.
- */
- beep()
- {
- putchar('\007');
- }
-
- /*
- * 'Ring' visual bell if available, otherwise audible bell.
- */
- flash()
- {
- /* If you get a syntax error on this routine,
- * you are not using the new curses.h! Put
- * it in this directory or in /usr/include (saving the old one).
- * And double check that you are linking with the new libcurses.a
- */
- if (flash_screen)
- putp(flash_screen);
- else
- beep();
- }
-
- /*
- * Return the baud rate of the current terminal.
- */
- baudrate()
- {
- #ifdef B9600
- if (_tty.sg_ospeed >= B9600)
- return(9600);
- #endif
- #ifdef B4800
- if (_tty.sg_ospeed >= B4800)
- return(4800);
- #endif
- return(1200);
- }
-
- erasechar() { return(_tty.sg_erase); }
- killchar() { return(_tty.sg_kill); }
- #endif
- SHAR_EOF
- if test 11742 -ne "`wc -c < 'hacks.c'`"
- then
- echo shar: error transmitting "'hacks.c'" '(should have been 11742 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'help.c'" '(2137 characters)'
- if test -f 'help.c'
- then
- echo shar: will not over-write existing file "'help.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'help.c'
- /*
- *************
- * DISTRIBUTION NOTICE July 30 1985
- * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
- * Research Triangle Institute, (919) 541-7005.
- * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
- * Naval Research Laboratory, (202) 767-3365.
- * No claims or warranties of any sort are made for this distribution.
- * General permission is granted to copy, but not for profit,
- * any of this distribution, provided that this notice
- * is always included in the copies.
- *************
- */
- #include "wm.h"
-
-
- /*
- * print a command summary over the top of the screen, then redraw
- */
- helpmsg()
- {
- printf("Code Command Description\r\n");
- printf("---- ------- -----------\r\n");
- printf("%d..%d change Change to the named window\r\n",
- MINWINDOW, MAXWINDOWS-1);
- printf("d dump dump current window contents to a file\r\n");
- printf("h or ? help print this help message\r\n");
- printf("i identify identify windows\r\n");
- printf("k kill kill a window permanently\r\n");
- printf("l last change to last-used window\r\n");
- printf("m move move and/or change size of current window\r\n");
- printf("n new make a new window\r\n");
- printf("p prefix change WM prefix character (See EXECUTE below)\r\n");
- printf("q quit quit WM\r\n");
- printf("r redraw redraw entire screen\r\n");
- printf("s save save current window configuration\r\n");
- printf("t termcap reset $TERM and $TERMCAP of current window\r\n");
- printf("z suspend suspend WM (or spawn non-window subshell)\r\n");
-
- printf("----------------------------------------------------------\r\n");
-
- printf("To EXECUTE a command, type the WM prefix character (%s) then the command code.\r\n", mkprint(prefix));
- printf("To ENTER the prefix character itself, type it twice.\r\n");
- printf("To CANCEL a WM command before it executes, type <ESC> or <DEL>.\r\n");
- printf("For FUTHER INFORMATION, consult the 'wm' manual entry.\r\n");
-
- printf("------------------------------\r\n");
-
- printf("Now hit any key to return to WM");
- (void)fflush(stdout);
- }
- SHAR_EOF
- if test 2137 -ne "`wc -c < 'help.c'`"
- then
- echo shar: error transmitting "'help.c'" '(should have been 2137 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-